package com.example.joblinker.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.joblinker.dto.CreateReplyDTO;
import com.example.joblinker.dto.CreateTopicDTO;
import com.example.joblinker.dto.ForumSearchDTO;
import com.example.joblinker.entity.Board;
import com.example.joblinker.entity.Reply;
import com.example.joblinker.entity.Topic;
import com.example.joblinker.entity.User;
import com.example.joblinker.entity.Vote;
import com.example.joblinker.mapper.BoardMapper;
import com.example.joblinker.mapper.ReplyMapper;
import com.example.joblinker.mapper.TopicMapper;
import com.example.joblinker.mapper.UserMapper;
import com.example.joblinker.mapper.VoteMapper;
import com.example.joblinker.service.ForumService;
import com.example.joblinker.vo.BoardVO;
import com.example.joblinker.vo.ReplyVO;
import com.example.joblinker.vo.TopicVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.function.Function;

@Service
public class ForumServiceImpl implements ForumService {

    @Resource
    private BoardMapper boardMapper;

    @Resource
    private TopicMapper topicMapper;

    @Resource
    private ReplyMapper replyMapper;

    @Resource
    private VoteMapper voteMapper;

    @Resource
    private UserMapper userMapper;

    @Override
    public Map<String, Object> getForumStats() {
        // 统计板块数量
        LambdaQueryWrapper<Board> boardQuery = new LambdaQueryWrapper<>();
        boardQuery.eq(Board::getDeleted, 0);
        long boardCount = boardMapper.selectCount(boardQuery);

        // 统计话题数量
        LambdaQueryWrapper<Topic> topicQuery = new LambdaQueryWrapper<>();
        topicQuery.eq(Topic::getDeleted, 0);
        long topicCount = topicMapper.selectCount(topicQuery);

        // 统计回复数量
        LambdaQueryWrapper<Reply> replyQuery = new LambdaQueryWrapper<>();
        replyQuery.eq(Reply::getDeleted, 0);
        long replyCount = replyMapper.selectCount(replyQuery);

        // 统计用户数量（按照有发帖记录的用户统计）
        long userCount = 0;
        try {
            // 使用不同的查询方式获取发帖用户数
            LambdaQueryWrapper<Topic> userQuery = new LambdaQueryWrapper<>();
            userQuery.select(Topic::getUserId).groupBy(Topic::getUserId);
            List<Topic> userList = topicMapper.selectList(userQuery);
            userCount = userList.size();
        } catch (Exception e) {
            // 如果查询失败，使用默认值
            userCount = 1;
        }

        Map<String, Object> stats = new HashMap<>();
        stats.put("boardCount", boardCount);
        stats.put("topicCount", topicCount);
        stats.put("replyCount", replyCount);
        stats.put("userCount", userCount);
        return stats;
    }

    @Override
    public List<BoardVO> getAllBoards() {
        LambdaQueryWrapper<Board> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Board::getDeleted, 0)
                .orderByAsc(Board::getId);

        List<Board> boards = boardMapper.selectList(queryWrapper);
        return boards.stream().map(this::convertToBoardVO).collect(Collectors.toList());
    }

    @Override
    public List<TopicVO> getHotTopics(Integer limit) {
        if (limit == null || limit <= 0) {
            limit = 10;
        }

        LambdaQueryWrapper<Topic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Topic::getDeleted, 0)
                .orderByDesc(Topic::getVotes)
                .orderByDesc(Topic::getReplies)
                .orderByDesc(Topic::getViews)
                .last("LIMIT " + limit);

        List<Topic> topics = topicMapper.selectList(queryWrapper);
        return topics.stream().map(topic -> convertToTopicVO(topic, null)).collect(Collectors.toList());
    }

    @Override
    public Page<TopicVO> getLatestTopics(Integer page, Integer size) {
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 10;
        }

        Page<Topic> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Topic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Topic::getDeleted, 0)
                .orderByDesc(Topic::getCreateTime);

        Page<Topic> topicPage = topicMapper.selectPage(pageParam, queryWrapper);
        Page<TopicVO> voPage = new Page<>();
        BeanUtils.copyProperties(topicPage, voPage, "records");
        voPage.setRecords(topicPage.getRecords().stream()
                .map(topic -> convertToTopicVO(topic, null))
                .collect(Collectors.toList()));
        return voPage;
    }

    @Override
    public Map<String, Object> getBoardDetail(Long boardId, Integer page, Integer size, String filter, String keyword) {
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 10;
        }

        // 获取板块信息
        Board board = boardMapper.selectById(boardId);
        if (board == null || board.getDeleted() == 1) {
            throw new RuntimeException("板块不存在");
        }

        BoardVO boardVO = convertToBoardVO(board);

        // 查询话题列表
        Page<Topic> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Topic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Topic::getBoardId, boardId)
                .eq(Topic::getDeleted, 0);  // 确保只查询未删除的话题

        System.out.println("===== 查询板块话题 =====");
        System.out.println("板块ID: " + boardId);
        System.out.println("页码: " + page + ", 每页大小: " + size);

        // 根据过滤条件设置查询
        if ("essence".equals(filter)) {
            queryWrapper.eq(Topic::getIsEssence, 1);
            System.out.println("过滤条件: 精华");
        } else if ("hot".equals(filter)) {
            queryWrapper.orderByDesc(Topic::getViews, Topic::getVotes, Topic::getReplies);
            System.out.println("过滤条件: 热门");
        }

        // 根据关键词搜索
        if (keyword != null && !keyword.trim().isEmpty()) {
            queryWrapper.and(wrapper ->
                    wrapper.like(Topic::getTitle, keyword)
                            .or()
                            .like(Topic::getContent, keyword)
            );
            System.out.println("搜索关键词: " + keyword);
        }

        // 先按置顶排序，再按最近回复时间排序
        queryWrapper.orderByDesc(Topic::getIsTop, Topic::getLastReplyTime, Topic::getCreateTime);

        Page<Topic> topicPage = topicMapper.selectPage(pageParam, queryWrapper);
        System.out.println("查询到话题数: " + topicPage.getRecords().size());
        
        // 检查是否有已删除但仍被返回的话题
        for (Topic topic : topicPage.getRecords()) {
            System.out.println("话题ID: " + topic.getId() + ", 标题: " + topic.getTitle() + ", 删除状态: " + topic.getDeleted());
            if (topic.getDeleted() == 1) {
                System.out.println("警告: 发现已删除但仍被查询到的话题 ID: " + topic.getId());
            }
        }
        
        List<TopicVO> topicVOList = topicPage.getRecords().stream()
                .map(topic -> convertToTopicVO(topic, null))
                .collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("board", boardVO);
        result.put("topics", topicVOList);
        result.put("total", topicPage.getTotal());
        result.put("pages", topicPage.getPages());
        result.put("current", topicPage.getCurrent());
        result.put("size", topicPage.getSize());
        return result;
    }

    @Override
    public TopicVO getTopicDetail(Long topicId, Long userId) {
        Topic topic = topicMapper.selectById(topicId);
        if (topic == null || topic.getDeleted() == 1) {
            throw new RuntimeException("话题不存在");
        }

        // 增加浏览次数
        topic.setViews(topic.getViews() + 1);
        topicMapper.updateById(topic);

        return convertToTopicVO(topic, userId);
    }

    @Override
    public Page<ReplyVO> getTopicReplies(Long topicId, Integer page, Integer size, String sort, Long userId) {
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 10;
        }

        Page<Reply> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Reply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Reply::getTopicId, topicId)
                .eq(Reply::getDeleted, 0);

        // 根据排序方式设置查询
        if ("hot".equals(sort)) {
            queryWrapper.orderByDesc(Reply::getVotes, Reply::getCreateTime);
        } else {
            queryWrapper.orderByAsc(Reply::getCreateTime);
        }

        Page<Reply> replyPage = replyMapper.selectPage(pageParam, queryWrapper);
        Page<ReplyVO> voPage = new Page<>();
        BeanUtils.copyProperties(replyPage, voPage, "records");
        voPage.setRecords(replyPage.getRecords().stream()
                .map(reply -> convertToReplyVO(reply, userId))
                .collect(Collectors.toList()));
        return voPage;
    }

    @Override
    @Transactional
    public TopicVO createTopic(CreateTopicDTO createTopicDTO, Long userId) {
        // 检查用户
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查板块
        Board board = boardMapper.selectById(createTopicDTO.getBoardId());
        if (board == null || board.getDeleted() == 1) {
            throw new RuntimeException("板块不存在");
        }

        // 创建话题
        Topic topic = new Topic();
        topic.setTitle(createTopicDTO.getTitle());
        topic.setContent(createTopicDTO.getContent());
        topic.setBoardId(createTopicDTO.getBoardId());
        topic.setUserId(userId);
        topic.setViews(0);
        topic.setReplies(0);
        topic.setVotes(0);
        topic.setIsTop(0);
        topic.setIsEssence(0);
        topic.setDeleted(0);
        topic.setCreateTime(LocalDateTime.now());
        topic.setUpdateTime(LocalDateTime.now());

        topicMapper.insert(topic);

        // 更新板块话题数
        board.setTopicCount(board.getTopicCount() + 1);
        boardMapper.updateById(board);

        return convertToTopicVO(topic, userId);
    }

    @Override
    @Transactional
    public TopicVO updateTopic(Long topicId, CreateTopicDTO updateTopicDTO, Long userId) {
        Topic topic = topicMapper.selectById(topicId);
        if (topic == null || topic.getDeleted() == 1) {
            throw new RuntimeException("话题不存在");
        }

        // 检查是否是作者或管理员
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        boolean isAdmin = user.getRole() != null && user.getRole() == 0;
        boolean isAuthor = topic.getUserId().equals(userId);

        if (!isAdmin && !isAuthor) {
            throw new RuntimeException("没有权限修改该话题");
        }

        // 如果修改了板块，需要检查板块是否存在
        if (!topic.getBoardId().equals(updateTopicDTO.getBoardId())) {
            Board newBoard = boardMapper.selectById(updateTopicDTO.getBoardId());
            if (newBoard == null || newBoard.getDeleted() == 1) {
                throw new RuntimeException("目标板块不存在");
            }

            // 更新原板块和新板块的话题数
            Board oldBoard = boardMapper.selectById(topic.getBoardId());
            oldBoard.setTopicCount(oldBoard.getTopicCount() - 1);
            newBoard.setTopicCount(newBoard.getTopicCount() + 1);
            boardMapper.updateById(oldBoard);
            boardMapper.updateById(newBoard);

            // 更新话题的板块ID
            topic.setBoardId(updateTopicDTO.getBoardId());
        }

        // 更新话题内容
        topic.setTitle(updateTopicDTO.getTitle());
        topic.setContent(updateTopicDTO.getContent());
        topic.setUpdateTime(LocalDateTime.now());

        topicMapper.updateById(topic);

        return convertToTopicVO(topic, userId);
    }

    @Override
    @Transactional
    public boolean deleteTopic(Long topicId, Long userId) {
        // 查询话题
        Topic topic = topicMapper.selectById(topicId);
        System.out.println("====== 删除话题 ======");
        System.out.println("话题ID: " + topicId);
        System.out.println("当前用户ID: " + userId);
        
        if (topic == null || topic.getDeleted() == 1) {
            System.out.println("话题不存在或已被删除");
            throw new RuntimeException("话题不存在");
        }

        System.out.println("找到话题: " + topic.getTitle());
        
        // 检查是否是作者或管理员
        User user = userMapper.selectById(userId);
        if (user == null) {
            System.out.println("用户不存在");
            throw new RuntimeException("用户不存在");
        }

        System.out.println("用户角色: " + user.getRole());
        System.out.println("话题作者ID: " + topic.getUserId());
        
        boolean isAdmin = user.getRole() != null && user.getRole() == 2; // 修正：管理员角色值为2
        boolean isAuthor = topic.getUserId().equals(userId);
        
        System.out.println("是管理员: " + isAdmin);
        System.out.println("是作者: " + isAuthor);

        if (!isAdmin && !isAuthor) {
            System.out.println("权限检查失败：既不是管理员也不是作者");
            throw new RuntimeException("没有权限删除该话题");
        }

        // 使用LambdaUpdateWrapper进行部分字段更新，只设置deleted字段和updateTime字段
        LambdaUpdateWrapper<Topic> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Topic::getId, topicId)
                     .eq(Topic::getDeleted, 0)  // 确保只更新未删除的话题
                     .set(Topic::getDeleted, 1)
                     .set(Topic::getUpdateTime, LocalDateTime.now());
        
        int result = topicMapper.update(null, updateWrapper);
        
        System.out.println("话题删除更新结果: " + result + ", 使用LambdaUpdateWrapper专门更新deleted字段");
        
        if (result <= 0) {
            System.out.println("话题删除数据库操作失败");
            throw new RuntimeException("删除话题失败");
        }

        // 更新板块话题数
        Board board = boardMapper.selectById(topic.getBoardId());
        if (board != null) {
            // 确保话题数不会变成负数
            int newTopicCount = Math.max(0, board.getTopicCount() - 1);
            System.out.println("原板块话题数: " + board.getTopicCount() + ", 新板块话题数: " + newTopicCount);
            
            // 使用LambdaUpdateWrapper更新板块话题数
            LambdaUpdateWrapper<Board> boardUpdateWrapper = new LambdaUpdateWrapper<>();
            boardUpdateWrapper.eq(Board::getId, topic.getBoardId())
                              .set(Board::getTopicCount, newTopicCount);
            
            int boardUpdateResult = boardMapper.update(null, boardUpdateWrapper);
            System.out.println("板块更新结果: " + boardUpdateResult);
        } else {
            System.out.println("板块不存在，ID: " + topic.getBoardId());
        }

        // 统计该话题下的回复数
        LambdaQueryWrapper<Reply> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(Reply::getTopicId, topicId).eq(Reply::getDeleted, 0);
        Long replyCount = replyMapper.selectCount(countWrapper);
        
        System.out.println("话题回复数: " + replyCount);

        // 删除相关回复
        if (replyCount > 0) {
            LambdaUpdateWrapper<Reply> replyUpdateWrapper = new LambdaUpdateWrapper<>();
            replyUpdateWrapper.eq(Reply::getTopicId, topicId)
                    .eq(Reply::getDeleted, 0)  // 只更新未删除的回复
                    .set(Reply::getDeleted, 1)
                    .set(Reply::getUpdateTime, LocalDateTime.now());
            int replyUpdateResult = replyMapper.update(null, replyUpdateWrapper);
            System.out.println("回复删除更新结果: " + replyUpdateResult);
            
            // 更新板块回复数
            if (board != null) {
                // 确保回复数不会变成负数
                int newPostCount = Math.max(0, board.getPostCount() - replyCount.intValue());
                System.out.println("原板块回复数: " + board.getPostCount() + ", 新板块回复数: " + newPostCount);
                
                // 使用LambdaUpdateWrapper更新板块回复数
                LambdaUpdateWrapper<Board> boardPostUpdateWrapper = new LambdaUpdateWrapper<>();
                boardPostUpdateWrapper.eq(Board::getId, topic.getBoardId())
                                     .set(Board::getPostCount, newPostCount);
                
                int boardPostUpdateResult = boardMapper.update(null, boardPostUpdateWrapper);
                System.out.println("板块回复数更新结果: " + boardPostUpdateResult);
            }
        }

        System.out.println("话题删除操作完成: " + topicId);
        return true;
    }

    @Override
    @Transactional
    public ReplyVO createReply(CreateReplyDTO createReplyDTO, Long userId) {
        // 检查用户
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查话题
        Topic topic = topicMapper.selectById(createReplyDTO.getTopicId());
        if (topic == null || topic.getDeleted() == 1) {
            throw new RuntimeException("话题不存在");
        }

        // 检查父回复
        if (createReplyDTO.getParentId() != null) {
            Reply parentReply = replyMapper.selectById(createReplyDTO.getParentId());
            if (parentReply == null || parentReply.getDeleted() == 1) {
                throw new RuntimeException("被回复的内容不存在");
            }
        }

        // 创建回复
        Reply reply = new Reply();
        reply.setTopicId(createReplyDTO.getTopicId());
        reply.setContent(createReplyDTO.getContent());
        reply.setUserId(userId);
        reply.setParentId(createReplyDTO.getParentId());
        reply.setVotes(0);
        reply.setDeleted(0);
        reply.setCreateTime(LocalDateTime.now());
        reply.setUpdateTime(LocalDateTime.now());

        replyMapper.insert(reply);

        // 更新话题回复数和最后回复时间
        topic.setReplies(topic.getReplies() + 1);
        topic.setLastReplyTime(LocalDateTime.now());
        topicMapper.updateById(topic);

        // 更新板块回复总数
        Board board = boardMapper.selectById(topic.getBoardId());
        board.setPostCount(board.getPostCount() + 1);
        boardMapper.updateById(board);

        return convertToReplyVO(reply, userId);
    }

    @Override
    @Transactional
    public boolean deleteReply(Long replyId, Long userId) {
        System.out.println("====== 删除回复 ======");
        System.out.println("回复ID: " + replyId);
        System.out.println("当前用户ID: " + userId);
        
        Reply reply = replyMapper.selectById(replyId);
        if (reply == null || reply.getDeleted() == 1) {
            System.out.println("回复不存在或已被删除");
            throw new RuntimeException("回复不存在");
        }

        System.out.println("找到回复，所属话题ID: " + reply.getTopicId());
        
        // 检查是否是作者或管理员
        User user = userMapper.selectById(userId);
        if (user == null) {
            System.out.println("用户不存在");
            throw new RuntimeException("用户不存在");
        }

        System.out.println("用户角色: " + user.getRole());
        System.out.println("回复作者ID: " + reply.getUserId());
        
        boolean isAdmin = user.getRole() != null && user.getRole() == 2; // 修正：管理员角色值为2
        boolean isAuthor = reply.getUserId().equals(userId);
        
        System.out.println("是管理员: " + isAdmin);
        System.out.println("是作者: " + isAuthor);

        if (!isAdmin && !isAuthor) {
            System.out.println("权限检查失败：既不是管理员也不是作者");
            throw new RuntimeException("没有权限删除该回复");
        }

        // 使用LambdaUpdateWrapper进行部分字段更新，只设置deleted字段和updateTime字段
        LambdaUpdateWrapper<Reply> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Reply::getId, replyId)
                      .eq(Reply::getDeleted, 0)  // 确保只更新未删除的回复
                      .set(Reply::getDeleted, 1)
                      .set(Reply::getUpdateTime, LocalDateTime.now());
        
        int result = replyMapper.update(null, updateWrapper);
        
        System.out.println("回复删除更新结果: " + result + ", 使用LambdaUpdateWrapper专门更新deleted字段");
        
        if (result <= 0) {
            System.out.println("回复删除数据库操作失败");
            throw new RuntimeException("删除回复失败");
        }

        // 更新话题回复数
        Topic topic = topicMapper.selectById(reply.getTopicId());
        if (topic != null && topic.getDeleted() == 0) {
            // 确保回复数不会变成负数
            int newReplyCount = Math.max(0, topic.getReplies() - 1);
            System.out.println("原话题回复数: " + topic.getReplies() + ", 新话题回复数: " + newReplyCount);
            
            // 使用LambdaUpdateWrapper更新话题回复数
            LambdaUpdateWrapper<Topic> topicUpdateWrapper = new LambdaUpdateWrapper<>();
            topicUpdateWrapper.eq(Topic::getId, topic.getId())
                             .set(Topic::getReplies, newReplyCount);
            
            int topicUpdateResult = topicMapper.update(null, topicUpdateWrapper);
            System.out.println("话题更新结果: " + topicUpdateResult);
            
            // 更新板块回复总数
            Board board = boardMapper.selectById(topic.getBoardId());
            if (board != null) {
                // 确保回复总数不会变成负数
                int newPostCount = Math.max(0, board.getPostCount() - 1);
                System.out.println("原板块回复总数: " + board.getPostCount() + ", 新板块回复总数: " + newPostCount);
                
                // 使用LambdaUpdateWrapper更新板块回复总数
                LambdaUpdateWrapper<Board> boardUpdateWrapper = new LambdaUpdateWrapper<>();
                boardUpdateWrapper.eq(Board::getId, board.getId())
                                 .set(Board::getPostCount, newPostCount);
                
                int boardUpdateResult = boardMapper.update(null, boardUpdateWrapper);
                System.out.println("板块更新结果: " + boardUpdateResult);
            } else {
                System.out.println("板块不存在，ID: " + topic.getBoardId());
            }
        } else {
            System.out.println("话题不存在或已被删除, ID: " + reply.getTopicId());
        }

        System.out.println("====== 删除回复完成 ======");
        return true;
    }

    @Override
    @Transactional
    public boolean voteTopic(Long topicId, Long userId, boolean isUpvote) {
        // 检查话题是否存在
        Topic topic = topicMapper.selectById(topicId);
        if (topic == null || topic.getDeleted() == 1) {
            throw new RuntimeException("话题不存在");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查是否已点赞
        LambdaQueryWrapper<Vote> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Vote::getUserId, userId)
                .eq(Vote::getTargetId, topicId)
                .eq(Vote::getTargetType, 1) // 1表示话题
                .eq(Vote::getType, 1)
                .eq(Vote::getDeleted, 0);

        Vote vote = voteMapper.selectOne(queryWrapper);

        if (isUpvote) {
            // 点赞
            if (vote == null) {
                // 创建点赞记录
                vote = new Vote();
                vote.setUserId(userId);
                vote.setTargetId(topicId);
                vote.setTargetType(1); // 1表示话题
                vote.setType(1); // 1表示话题点赞
                vote.setDeleted(0);
                vote.setCreateTime(LocalDateTime.now());
                voteMapper.insert(vote);

                // 更新话题点赞数
                topic.setVotes(topic.getVotes() + 1);
                topicMapper.updateById(topic);
            }
        } else {
            // 取消点赞
            if (vote != null) {
                // 逻辑删除点赞记录
                vote.setDeleted(1);
                voteMapper.updateById(vote);

                // 更新话题点赞数
                topic.setVotes(topic.getVotes() - 1);
                topicMapper.updateById(topic);
            }
        }

        return true;
    }

    @Override
    @Transactional
    public boolean voteReply(Long replyId, Long userId, boolean isUpvote) {
        // 检查回复是否存在
        Reply reply = replyMapper.selectById(replyId);
        if (reply == null || reply.getDeleted() == 1) {
            throw new RuntimeException("回复不存在");
        }

        // 检查用户是否存在
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 检查是否已点赞
        LambdaQueryWrapper<Vote> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Vote::getUserId, userId)
                .eq(Vote::getTargetId, replyId)
                .eq(Vote::getTargetType, 2) // 2表示回复
                .eq(Vote::getType, 2)
                .eq(Vote::getDeleted, 0);

        Vote vote = voteMapper.selectOne(queryWrapper);

        if (isUpvote) {
            // 点赞
            if (vote == null) {
                // 创建点赞记录
                vote = new Vote();
                vote.setUserId(userId);
                vote.setTargetId(replyId);
                vote.setTargetType(2); // 2表示回复
                vote.setType(2); // 2表示回复点赞
                vote.setDeleted(0);
                vote.setCreateTime(LocalDateTime.now());
                voteMapper.insert(vote);

                // 更新回复点赞数
                reply.setVotes(reply.getVotes() + 1);
                replyMapper.updateById(reply);
            }
        } else {
            // 取消点赞
            if (vote != null) {
                // 逻辑删除点赞记录
                vote.setDeleted(1);
                voteMapper.updateById(vote);

                // 更新回复点赞数
                reply.setVotes(reply.getVotes() - 1);
                replyMapper.updateById(reply);
            }
        }

        return true;
    }

    @Override
    public Page<TopicVO> searchTopics(ForumSearchDTO searchDTO) {
        Integer page = searchDTO.getPage();
        Integer size = searchDTO.getSize();
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 10;
        }

        Page<Topic> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Topic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Topic::getDeleted, 0);

        // 按板块筛选
        if (searchDTO.getBoardId() != null) {
            queryWrapper.eq(Topic::getBoardId, searchDTO.getBoardId());
        }

        // 按关键词搜索
        if (searchDTO.getKeyword() != null && !searchDTO.getKeyword().trim().isEmpty()) {
            queryWrapper.and(wrapper ->
                    wrapper.like(Topic::getTitle, searchDTO.getKeyword())
                            .or()
                            .like(Topic::getContent, searchDTO.getKeyword())
            );
        }

        // 按照排序方式设置查询
        if ("hot".equals(searchDTO.getSort())) {
            queryWrapper.orderByDesc(Topic::getViews, Topic::getVotes, Topic::getReplies);
        } else {
            queryWrapper.orderByDesc(Topic::getCreateTime);
        }

        Page<Topic> topicPage = topicMapper.selectPage(pageParam, queryWrapper);
        Page<TopicVO> voPage = new Page<>();
        BeanUtils.copyProperties(topicPage, voPage, "records");
        voPage.setRecords(topicPage.getRecords().stream()
                .map(topic -> convertToTopicVO(topic, null))
                .collect(Collectors.toList()));
        return voPage;
    }

    @Override
    public Page<TopicVO> getUserTopics(Long userId, Integer page, Integer size) {
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 10;
        }

        Page<Topic> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Topic> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Topic::getUserId, userId)
                .eq(Topic::getDeleted, 0)
                .orderByDesc(Topic::getCreateTime);

        Page<Topic> topicPage = topicMapper.selectPage(pageParam, queryWrapper);
        Page<TopicVO> voPage = new Page<>();
        BeanUtils.copyProperties(topicPage, voPage, "records");
        voPage.setRecords(topicPage.getRecords().stream()
                .map(topic -> convertToTopicVO(topic, userId))
                .collect(Collectors.toList()));
        return voPage;
    }

    @Override
    public Page<ReplyVO> getUserReplies(Long userId, Integer page, Integer size) {
        if (page == null || page <= 0) {
            page = 1;
        }
        if (size == null || size <= 0) {
            size = 10;
        }

        Page<Reply> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Reply> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Reply::getUserId, userId)
                .eq(Reply::getDeleted, 0)
                .orderByDesc(Reply::getCreateTime);

        Page<Reply> replyPage = replyMapper.selectPage(pageParam, queryWrapper);
        Page<ReplyVO> voPage = new Page<>();
        BeanUtils.copyProperties(replyPage, voPage, "records");
        voPage.setRecords(replyPage.getRecords().stream()
                .map(reply -> convertToReplyVO(reply, userId))
                .collect(Collectors.toList()));
        return voPage;
    }

    @Override
    @Transactional
    public boolean setTopicEssence(Long topicId, boolean isEssence, Long userId) {
        // 检查话题是否存在
        Topic topic = topicMapper.selectById(topicId);
        if (topic == null || topic.getDeleted() == 1) {
            throw new RuntimeException("话题不存在");
        }

        // 检查用户是否是管理员
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        boolean isAdmin = user.getRole() != null && user.getRole() == 0;
        if (!isAdmin) {
            throw new RuntimeException("没有权限设置精华");
        }

        // 更新话题精华状态
        topic.setIsEssence(isEssence ? 1 : 0);
        topic.setUpdateTime(LocalDateTime.now());
        topicMapper.updateById(topic);

        return true;
    }

    @Override
    @Transactional
    public boolean setTopicTop(Long topicId, boolean isTop, Long userId) {
        // 检查话题是否存在
        Topic topic = topicMapper.selectById(topicId);
        if (topic == null || topic.getDeleted() == 1) {
            throw new RuntimeException("话题不存在");
        }

        // 检查用户是否是管理员
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        boolean isAdmin = user.getRole() != null && user.getRole() == 0;
        if (!isAdmin) {
            throw new RuntimeException("没有权限设置置顶");
        }

        // 更新话题置顶状态
        topic.setIsTop(isTop ? 1 : 0);
        topic.setUpdateTime(LocalDateTime.now());
        topicMapper.updateById(topic);

        return true;
    }

    /**
     * 将Board实体转换为BoardVO
     */
    private BoardVO convertToBoardVO(Board board) {
        if (board == null) {
            return null;
        }

        BoardVO vo = new BoardVO();
        BeanUtils.copyProperties(board, vo);

        // 设置版主名称
        if (board.getModeratorId() != null) {
            User moderator = userMapper.selectById(board.getModeratorId());
            if (moderator != null) {
                vo.setModerator(moderator.getUsername());
            }
        }

        return vo;
    }

    /**
     * 将Topic实体转换为TopicVO
     */
    private TopicVO convertToTopicVO(Topic topic, Long userId) {
        if (topic == null) {
            return null;
        }

        TopicVO vo = new TopicVO();
        BeanUtils.copyProperties(topic, vo);

        // 设置布尔类型的字段
        vo.setIsTop(topic.getIsTop() != null && topic.getIsTop() == 1);
        vo.setIsEssence(topic.getIsEssence() != null && topic.getIsEssence() == 1);

        // 设置板块名称
        Board board = boardMapper.selectById(topic.getBoardId());
        if (board != null) {
            vo.setBoardName(board.getName());
        }

        // 设置作者信息
        User author = userMapper.selectById(topic.getUserId());
        if (author != null) {
            Map<String, Object> authorInfo = new HashMap<>();
            authorInfo.put("id", author.getId());
            authorInfo.put("username", author.getUsername());
            // 使用用户的实际头像，如果没有则使用默认头像
            authorInfo.put("avatar", author.getAvatar() != null ? author.getAvatar() : "/images/default-avatar.png");
            vo.setAuthor(authorInfo);
        }

        // 设置当前用户是否已点赞
        if (userId != null) {
            LambdaQueryWrapper<Vote> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Vote::getUserId, userId)
                    .eq(Vote::getTargetId, topic.getId())
                    .eq(Vote::getTargetType, 1) // 1表示话题
                    .eq(Vote::getType, 1)
                    .eq(Vote::getDeleted, 0);
            Vote vote = voteMapper.selectOne(queryWrapper);
            vo.setIsVoted(vote != null);
        }

        // 设置话题摘要
        if (topic.getContent() != null) {
            String content = topic.getContent();
            // 去除HTML标签
            content = content.replaceAll("<[^>]+>", "");
            // 截取前100个字符作为摘要
            if (content.length() > 100) {
                content = content.substring(0, 100) + "...";
            }
            vo.setExcerpt(content);
        }

        return vo;
    }

    /**
     * 将Reply实体转换为ReplyVO
     */
    private ReplyVO convertToReplyVO(Reply reply, Long userId) {
        if (reply == null) {
            return null;
        }

        ReplyVO vo = new ReplyVO();
        BeanUtils.copyProperties(reply, vo);

        // 设置作者信息
        User author = userMapper.selectById(reply.getUserId());
        if (author != null) {
            Map<String, Object> authorInfo = new HashMap<>();
            authorInfo.put("id", author.getId());
            authorInfo.put("username", author.getUsername());
            // 使用用户的实际头像，如果没有则使用默认头像
            authorInfo.put("avatar", author.getAvatar() != null ? author.getAvatar() : "/images/default-avatar.png");
            vo.setAuthor(authorInfo);
        }

        // 设置被引用的回复信息
        if (reply.getParentId() != null) {
            Reply parentReply = replyMapper.selectById(reply.getParentId());
            if (parentReply != null && parentReply.getDeleted() == 0) {
                Map<String, Object> quotedInfo = new HashMap<>();
                quotedInfo.put("id", parentReply.getId());
                quotedInfo.put("content", parentReply.getContent());

                User quotedAuthor = userMapper.selectById(parentReply.getUserId());
                if (quotedAuthor != null) {
                    Map<String, Object> authorInfo = new HashMap<>();
                    authorInfo.put("id", quotedAuthor.getId());
                    authorInfo.put("name", quotedAuthor.getUsername());
                    // 使用用户的实际头像，如果没有则使用默认头像
                    authorInfo.put("avatar", quotedAuthor.getAvatar() != null ? quotedAuthor.getAvatar() : "/images/default-avatar.png");
                    quotedInfo.put("author", authorInfo);
                } else {
                    // 如果作者已删除，提供默认作者信息
                    Map<String, Object> defaultAuthor = new HashMap<>();
                    defaultAuthor.put("id", 0);
                    defaultAuthor.put("name", "已删除用户");
                    defaultAuthor.put("avatar", null);
                    quotedInfo.put("author", defaultAuthor);
                }

                vo.setQuoted(quotedInfo);
            }
        }

        // 设置当前用户是否已点赞
        if (userId != null) {
            LambdaQueryWrapper<Vote> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Vote::getUserId, userId)
                    .eq(Vote::getTargetId, reply.getId())
                    .eq(Vote::getTargetType, 2) // 2表示回复
                    .eq(Vote::getType, 2)
                    .eq(Vote::getDeleted, 0);
            Vote vote = voteMapper.selectOne(queryWrapper);
            vo.setIsVoted(vote != null);
        }

        return vo;
    }
} 